import path from "path";
import { BaseServerCfg, ConnString, getConfig, startWatchConfig } from "./shared/tsgfServer/gfConfigMgr";
import { getRedisClient, initRedisClient, RedisClient, RedisConfig } from "./shared/tsgfServer/redisHelper";
import { logger } from "./shared/tsgf/logger";
import { MySqlFactory } from "./shared/tsgfServer/DbHelper";
import { IClusterNodeCfg } from "./shared/tsgfServer/cluster/ClusterMgr";
import { parseProcessArgv } from "./shared/tsgf/Utils";

let processArgs = parseProcessArgv(['gfConfigFile', 'loadXprofiler'], process.argv.splice(2));
let gfConfigFile = processArgs['gfConfigFile'] ?? '../gf.server.config.json';

if (processArgs['loadXprofiler'] === 'true') {
    require('xprofiler').start();
}

let serverConfigPath = path.resolve(__dirname, gfConfigFile);

export interface IClusterCfg extends BaseServerCfg {
    /**配置所有可以连接集群的节点 */
    nodeList: IClusterNodeCfg[];
}

export enum RunServerKey {
    HallServer = "HallServer",
    GameServerCluster = "GameServerCluster",
    MatchServerCluster = "MatchServerCluster",
    GameServer = "GameServer",
    MatchServer = "MatchServer",
    DemoServer = "DemoServer",
}

export interface IServerConfig {
    /**redis配置 */
    redisConfig: RedisConfig;
    /**所有数据库连接配置*/
    connString: ConnString;
    /**大厅服务配置*/
    hallServer: BaseServerCfg;
    /**游戏服务器集群管理服务配置*/
    gameServerCluster: IClusterCfg;
    /**匹配服务器集群管理服务配置*/
    matchServerCluster: IClusterCfg;
    /**游戏服务器*/
    gameServer: IGameServerCfg;
    /**匹配服务器*/
    matchServer: IMatchServerCfg;
    /**示例应用的用户系统接入服务 配置*/
    demoServer: BaseServerCfg;
    /**当前实例要启动哪些服务*/
    runServer: RunServerKey[];
}

export interface IGameServerCfg {
    /**集群的内网连接地址*/
    clusterWSUrl: string;
    /**集群节点ID（也可以视为服务器ID），集群内唯一，需要和集群服务的配置里一致 */
    clusterNodeId: string;
    /**本节点的集群连接密钥，需要和集群服务的配置里一致 */
    clusterKey: string;

    /**服务器名称 */
    serverName: string;
    /**服务器外网连接地址 */
    serverUrl: string;
    /**服务侦听的端口*/
    listenPort: number;
    /**拓展数据,不同的服务器不同的版本各不相同,将输出给获取服务器列表的客户端 */
    extendData?: any;
}

export interface IMatchServerCfg {
    /**集群的内网连接地址*/
    clusterWSUrl: string;
    /**集群节点ID（也可以视为服务器ID），集群内唯一，需要和集群服务的配置里一致 */
    clusterNodeId: string;
    /**本节点的集群连接密钥，需要和集群服务的配置里一致 */
    clusterKey: string;

    /**服务器名称 */
    serverName: string;
}

/**开始监控gf.clusterServer.config.json配置, 并返回获取到的配置对象 */
export function startWatchServerConfig(): IServerConfig {
    let ret = startWatchConfig(serverConfigPath, () => {
        let cfg = getServerConfig();
        if (cfg.redisConfig) {
            //配置文件有更新,重置一下redis客户端
            initRedisClient(cfg.redisConfig);
        } else {
            logger.error("gf.clusterServer.config.json => redisConfig未配置!");
        }
    });
    if (!ret.succ) {
        logger.error(ret.err);
    }
    let cfg = getServerConfig();
    if (cfg.redisConfig) {
        initRedisClient(cfg.redisConfig);
    } else {
        logger.error("gf.clusterServer.config.json => redisConfig未配置!");
    }
    return ret.data as IServerConfig;
}

/**获取gf.clusterServer.config.json配置，配置文件有变化会自动读取最新的*/
export function getServerConfig(): IServerConfig {
    let ret = getConfig(serverConfigPath);
    if (!ret.succ) {
        logger.error(ret.err);
    }
    return ret.data as IServerConfig;
}
/**获取gf.clusterServer.config.json配置中的redis客户端实例，配置文件有变化会自动使用最新的*/
export async function getServerRedisClient(reuseClient: boolean = true): Promise<RedisClient> {
    return await getRedisClient(reuseClient);
}

/**实现当前项目全局定义的 获取应用数据库连接实例 的方法*/
if (!globalThis.getAppDbHelper) {
    globalThis.getAppDbHelper = function () {
        return MySqlFactory.getMySqlDbHelper(getServerConfig().connString.appDb.mysql);
    }

}